package com.nanako.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nanako.common.R;
import com.nanako.dto.DishDto;
import com.nanako.entity.*;
import com.nanako.exception.CascadingDeleteException;
import com.nanako.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {
    @Autowired
    private DishService dishService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SetmealService setmealService;
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    /**
     * 添加菜品
     */
    @PostMapping
    public R saveDish(@RequestBody DishDto dishDto) {
        redisTemplate.delete(Objects.requireNonNull(redisTemplate.keys("dish*")));
        List<DishFlavor> flavors = dishDto.getFlavors();
        dishService.save(dishDto);

        //判断是否选择了口味
        if (flavors != null && flavors.size() > 0) {
            //保存菜品的口味数据 需要注意：DishFlavor中dishId是没有数据的，
            // 所以需要手动设置
            Long dishId = dishDto.getId();//获取菜品id
            for (DishFlavor flavor : flavors) {
                flavor.setDishId(dishId);
                dishFlavorService.save(flavor);
            }
        }
        return R.success("添加成功☆*: .｡. o(≧▽≦)o .｡.:*☆");
    }

    /**
     * 分页查询菜品数据
     */
    @GetMapping("/page")
    public R pageQuery(int page, int pageSize, String name) {
        // 创建page对象，设置当前页和每页大小
        IPage<Dish> pageInfo = new Page<>(page, pageSize);
        // 封装查询条件 where name like '%%'
        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        qw.like(StringUtils.isNotEmpty(name), Dish::getName, name)
                .orderByAsc(Dish::getSort)
                .orderByDesc(Dish::getUpdateTime);
        //开始查询
        dishService.page(pageInfo, qw);
        long total = pageInfo.getTotal();//总条数
        List<Dish> records = pageInfo.getRecords();// 查询列表数据

        Map map = new HashMap();
        map.put("total", (int) total);
        // records: List<Dish>
        // 只有菜品分类id：categoryId，没有分类名称
        // 根据菜品分类id，查询菜品分类数据。在set进去
        List<DishDto> dishDtos = records.stream().map((dish) -> {
            Category category = categoryService.getById(dish.getCategoryId());
            String categoryName = category.getName();
            DishDto dishDto = new DishDto();
            dishDto.setCategoryName(categoryName);
            BeanUtils.copyProperties(dish, dishDto);
            return dishDto;
        }).collect(Collectors.toList());


        map.put("records", dishDtos);
        return R.success(map);
    }

    @GetMapping("/{id}")
    public R queryOneDish(@PathVariable Long id) {
        // 获取菜品信息
        Dish dish = dishService.getById(id);
        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DishFlavor::getDishId, id);
        // 获取菜品对应的口味
        List<DishFlavor> dishFlavors = dishFlavorService.list(wrapper);
        // 创建返回的DishDto对象
        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dish, dishDto);
        dishDto.setFlavors(dishFlavors);
        return R.success(dishDto);
    }

    @PutMapping
    public R update(@RequestBody DishDto dishDto) {
        redisTemplate.delete(Objects.requireNonNull(redisTemplate.keys("dish*")));
        if (dishService.updateDishFlavor(dishDto)) {
            return R.success("添加成功");
        }
        return R.error("添加失败≡(▔﹏▔)≡");

    }

    @DeleteMapping
    public R removeBatch(@RequestParam ArrayList<Long> ids) {
        redisTemplate.delete(Objects.requireNonNull(redisTemplate.keys("dish*")));
        log.info("接收到的id" + ids);
        LambdaQueryWrapper<SetmealDish> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SetmealDish::getDishId, ids);
        setmealDishService.list(wrapper).forEach(setmealDish -> {
            if (setmealService.getById(setmealDish.getSetmealId()).getStatus() == 1) {
                throw new CascadingDeleteException("菜品有套餐正在售卖,不能删除");
            }
        });
        dishService.deleteDishByIds(ids);
        return R.success("删除成功");
    }

    /**
     * 批量起售停售
     *
     * @param status
     * @param ids
     * @return
     */
    @PostMapping("/status/{status}")
    public R startAndStopBatch(@PathVariable int status, @RequestParam ArrayList<Long> ids) {
        redisTemplate.delete(Objects.requireNonNull(redisTemplate.keys("dish*")));
        LambdaUpdateWrapper<Dish> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Dish::getStatus, status).in(Dish::getId, ids);
        // 如果菜品停售的话,查看相关套餐是否为起售,为起售的话则不能停售菜品
        if (status == 0) {
            LambdaQueryWrapper<SetmealDish> setmealDishWrapper = new LambdaQueryWrapper<>();
            setmealDishWrapper.in(SetmealDish::getDishId, ids);
            setmealDishService.list(setmealDishWrapper).forEach(setmealDish -> {
                if (setmealService.getById(setmealDish.getSetmealId()).getStatus() == 1) {
                    throw new CascadingDeleteException("菜品有套餐正在售卖,不能停售");
                }
            });
            dishService.update(wrapper);
            return R.success("停售成功☆*: .｡. o(≧▽≦)o .｡.:*☆");
        }else {
            dishService.update(wrapper);
        }
        return R.success("起售成功☆*: .｡. o(≧▽≦)o .｡.:*☆");
    }

    @GetMapping("/list")
    public R queryDishList(Long categoryId) {
        Object dishDtoCache = redisTemplate.opsForValue().get("dish:category:" + categoryId);
        if (ObjectUtils.isNotEmpty(dishDtoCache)) {
            return R.success(dishDtoCache);
        }
        // 创建查询条件对象
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Dish::getCategoryId, categoryId);
        // 条件查询dish并封装对应的dto对象
        List<DishDto> dishDtos = dishService.list(wrapper).stream().map(dish -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(dish, dishDto);
            List<DishFlavor> dishFlavors = dishFlavorService.list(new LambdaQueryWrapper<DishFlavor>()
                    .eq(DishFlavor::getDishId, dish.getId()));
            Category category = categoryService.getOne(new LambdaQueryWrapper<Category>()
                    .eq(Category::getId, dish.getCategoryId()));
            dishDto.setFlavors(dishFlavors);
            dishDto.setCategoryName(category.getName());
            return dishDto;
        }).toList();
        redisTemplate.opsForValue().set("dish:category:" + categoryId, dishDtos);
        return R.success(dishDtos);
    }
}
